package com.cjx.print.utils;

import android.content.Context;
import android.os.Environment;
import android.util.Log;

import com.cjx.print.BuildConfig;
import com.cjx.print.Constants;

import java.io.File;
import java.io.FileDescriptor;
import java.io.FileOutputStream;
import java.io.IOException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Locale;
import java.util.TimeZone;

/**
 * Created by cjx on 2019/8/7
 * 说明：保存日志到本地文件
 */
public class LogUtil {

    private static LogUtil log;

    private boolean open = true;

    private int count = 0;

    private String logPath;
    private File currentLogFile;

    public static LogUtil getInstance() {
        if (log == null) {
            synchronized (LogUtil.class) {
                if (log == null) {
                    log = new LogUtil();
                }
            }
        }
        return log;
    }


    public void initLogFile(Context context) {
        initLogFile(context, null, new Date());
    }

    public void initLogFile(Context context, String dir) {
        initLogFile(context, dir, new Date());
    }

    public void initLogFile(Context context, String dir, Date newDate) {
        SimpleDateFormat sdf = new SimpleDateFormat("yy-MM-dd", Locale.CHINA);
        String fileName = "YLSC_" + sdf.format(newDate);
        String logFilePath;
        synchronized (LogUtil.class) {
            if (dir == null) {
                dir = getDiskCacheDir(context) + "/log/";
            }
            logPath = dir;
            mkDir(dir);
            logFilePath = dir + fileName + ".txt";
            currentLogFile = new File(logFilePath);
            if (!currentLogFile.exists()) {
                try {
                    currentLogFile.createNewFile();
                } catch (IOException ignore) {
                }
            }
        }
        //考虑到网络时间没校准的时候
//        checkAndDelLog();
    }

    public void deleteHistory(long lastTime) {
        File[] logFiles = new File[]{
                new File(Constants.FILE_LOG_RUN_DIR)
        };
        long current = System.currentTimeMillis();
        for (File logFile : logFiles) {
            File[] logs = logFile.listFiles();
            if (logs == null) {
                continue;
            }
            for (File log : logs) {
                String name = log.getName();
                if (name.endsWith(".txt")) {
                    try {
                        if (log.lastModified() < lastTime) { // 30天前的日志， 要删除
                            LogUtil.getInstance().e("DELETE", "删除 " + name + " = " + log.delete());
                        }
                    } catch (Exception ignore) {
                    }
                }
            }
        }
    }

    // 设置是否启用日志功能
    public void setLogSwitch(boolean open) {
        this.open = open;
    }

    private void internalSaveLog(String tag, String msg) {
        if (!open) {
            return;
        }
        if (currentLogFile != null) {
            try {
                //     2021-09-26 15:05:39.714 6218-6251/
                FileOutputStream fileOutputStream = new FileOutputStream(currentLogFile, true);
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss.SSS", Locale.CHINA);
                byte[] bytes = (sdf.format(new Date()) + " " + android.os.Process.myPid() + "-" + android.os.Process.myTid() + "/" + tag + ":" + msg + "\n").getBytes();
                fileOutputStream.write(bytes);
                fileOutputStream.flush();

                if (count++ > 8) {
                    //将数据同步到达物理存储设备
                    try {
                        FileDescriptor fd = fileOutputStream.getFD();
                        fd.sync();
                    } catch (Exception ignored) {
                    }
                    count = 0;
                }

                fileOutputStream.close();
            } catch (Exception ignored) {
            }
        }
        e(tag, msg);
    }

    /**
     * 打印日志并保存到文件，需要先调用{@link #initLogFile(Context)}初始化日志路径才生效
     *
     * @param tag 日志标签
     * @param msg 日志内容
     */
    public void log(String tag, String msg) {
        if (msg.length() > 4000) {
            for (int i = 0; i < msg.length(); i += 4000) {
                if (i + 4000 < msg.length())
                    internalSaveLog(tag, msg.substring(i, i + 4000));
                else
                    internalSaveLog(tag, msg.substring(i));
            }
        } else {
            //直接打印
            internalSaveLog(tag, msg);
        }
    }


    public void e(String tag, String msg) {
        if (BuildConfig.DEBUG) {
            Log.e(tag, msg);
        }
    }

    /**
     * 获取程序缓存路径
     */
    public static String getDiskCacheDir(Context context) {
        boolean hasExternal = Environment.MEDIA_MOUNTED.equals(Environment.getExternalStorageState());
        File cacheDir = hasExternal ? context.getExternalCacheDir() : context.getCacheDir();
        return cacheDir.getAbsolutePath();
    }


    /**
     * 创建当前目录的文件夹
     */
    private void mkDir(String filePath) {
        File file = new File(filePath);
        if (!file.exists()) {
            file.mkdirs();
        }
    }

    public String log(String tag, Exception ex) {
        try {
            StringBuilder stringBuilder = new StringBuilder();
            StackTraceElement[] stackTraceElements = ex.getStackTrace();
            for (StackTraceElement element : stackTraceElements) {
                stringBuilder.append("\n" + element.toString());
            }
            log(tag, stringBuilder.toString());
            return stringBuilder.toString();
        } catch (Exception ignore) {
        }
        return "";
    }

    public String log(String tag, Throwable ex) {
        try {
            StringBuilder stringBuilder = new StringBuilder();
            StackTraceElement[] stackTraceElements = ex.getStackTrace();
            for (StackTraceElement element : stackTraceElements) {
                stringBuilder.append("\n" + element.toString());
            }
            log(tag, stringBuilder.toString());
            return stringBuilder.toString();
        } catch (Exception ignore) {
        }
        return "";
    }


    public static long getEffectiveTime() {
        SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");// HH:mm:ss
        simpleDateFormat.setTimeZone(TimeZone.getTimeZone("Asia/Shanghai"));
        try {
            return simpleDateFormat.parse("2021-01-01").getTime();
        } catch (ParseException ignore) {
        }
        return 0;
    }

    public File getLogDir() {
        return currentLogFile.getParentFile();
    }
}
